use lib_core::model::user::{User, UserBmc, UserFilter, UserForCreate, UserForUpdate};
use lib_rpc_core::{prelude::*, rpc_result::DataRpcResult, ParamsIded};

pub fn rpc_router_builder() -> RouterBuilder {
    router_builder!(
        // Same as RpcRouter::new().add...
        get_user,
        list_users,
        create_user,
        update_user,
        delete_user,
        search_users
    )
}

pub async fn get_user(
    ctx: Ctx,
    mm: ModelManager,
    params: ParamsIded,
) -> Result<DataRpcResult<User>> {
    let entity: User = UserBmc::get(&ctx, &mm, params.id).await?;
    Ok(entity.into())
}

pub async fn list_users(
    ctx: Ctx,
    mm: ModelManager,
    params: ParamsList<UserFilter>,
) -> Result<DataRpcResult<Vec<User>>> {
    let entities = UserBmc::list(&ctx, &mm, params.filters, params.list_options).await?;
    Ok(entities.into())
}

pub async fn create_user(
    ctx: Ctx,
    mm: ModelManager,
    params: ParamsForCreate<UserForCreate>,
) -> Result<DataRpcResult<User>> {
    let ParamsForCreate { data } = params;
    let id = UserBmc::create(&ctx, &mm, data).await?;
    let entity: User = UserBmc::get(&ctx, &mm, id).await?;
    Ok(entity.into())
}

pub async fn update_user(
    ctx: Ctx,
    mm: ModelManager,
    params: ParamsForUpdate<UserForUpdate>,
) -> Result<DataRpcResult<User>> {
    let ParamsForUpdate { id, data } = params;
    UserBmc::update(&ctx, &mm, id, data).await?;
    let entity: User = UserBmc::get(&ctx, &mm, id).await?;
    Ok(entity.into())
}

pub async fn delete_user(
    ctx: Ctx,
    mm: ModelManager,
    params: ParamsIded,
) -> Result<DataRpcResult<User>> {
    let ParamsIded { id } = params;
    let entity: User = UserBmc::get(&ctx, &mm, id).await?;
    UserBmc::delete(&ctx, &mm, id).await?;
    Ok(entity.into())
}

pub async fn search_users() -> Result<DataRpcResult<String>> {
    Ok(String::from("custom1 router").into())
}
